<?php

namespace app\common\logic;


use addons\leescore\model\Cart;
use app\admin\model\Leeaddress;
use app\admin\model\LeescoreCategory;
use app\admin\model\LeescoreGoods;
use app\admin\model\LeescoreOrder;
use app\admin\model\LeescoreOrderGoods;
use app\common\library\Auth;
use app\common\utils\Utils;
use fast\Random;
use fast\Tree;
use think\Collection;
use think\Db;
use think\Exception;
use think\exception\ValidateException;
use think\Request;

/**
 * 积分商城
 */
class LeescoreLogic
{

    protected $modelPool = [
        /**
         * 分类模型
         * @var \app\admin\model\LeescoreCategory
         */
        'categoryModel' => null,  //分类模型
        'goodsModel' => null,  //商品模型
        'orderModel' => null,//订单模型
        'orderGoodsModel' => null,//订单商品
        'cartModel' => null
    ];
    protected $tree = null;

    public function __get($name)
    {
        if(array_key_exists($name,$this->modelPool)){
            if ($this->modelPool[$name] == null) {
                switch ($name) {
                    case 'categoryModel': $this->modelPool[$name] = new LeescoreCategory();break;
                    case 'goodsModel': $this->modelPool[$name] = new LeescoreGoods();break;
                    case 'orderModel': $this->modelPool[$name] = new LeescoreOrder();break;
                    case 'orderGoodsModel': $this->modelPool[$name] = new LeescoreOrderGoods();break;
                    case 'cartModel': $this->modelPool[$name] = new Cart();break;
                }
            }

            return $this->modelPool[$name];
        } else {
            throw new ValidateException('参数错误');
        }
    }


    //排除字段
    protected $extraField = ['body', 'pics', 'fenxiao_status'];

    //默认排序
    public $order = [
        'weigh'=> 'desc',
        'createtime' => 'desc'
    ];
    private $auth = null;

    protected $row = 15;
    protected $request = null;
    public function __construct(Request $request = null)
    {
        $this->request = is_null($request) ? Request::instance() : $request;
        $this->auth = Auth::instance();

        $cate = $this->categoryModel->getLeescoreCategory();

        $this->tree = Tree::instance()->init($cate, 'category_id');
    }

    /*获取分类树形数组*/
    public function getTreeArray() {
        return $this->tree->getTreeArray(0);
    }
    /**
     * 设置订单
     * @return \app\common\logic\LeescoreLogic
     */
    public function setOrder($order) {
        foreach ($order as $k => $v) {
            if (!in_array($v, ['asc', 'desc'])) {
                throw new ValidateException('排序字段错误');
            }
        }
        if ($order) {
            $this->order = $order;
        }

        return $this;
    }

    /**
     * 获取分类
     * @param $limit 限制条数  null为不限制
     * @return Collection
     */
    public function getCategory($limit = null) {
        $where['status'] = 'normal';
        $where['topid'] = 0;  //顶级id
        $order = [
            'weigh' => 'desc',
            'createtime' => 'desc'
        ];
        $model = $this->categoryModel->where($where)->order($order);
        if ($limit != null) {
            return $model->limit($limit)->select();
        } else {
            return $model->select();
        }
    }

    /**包含自身*/
    public function getChildIds($id) {
        return $this->tree->getChildrenIds($id, true);
    }
    /**
     * 获取商品
     */
    public function getGoodsList($where) {
        $where['status'] = 2;
        $list = $this->goodsModel
            ->field($this->extraField, true)
            ->where($where)
            ->order($this->order)
            ->paginate($this->row);

        return $list;
    }

    /** 商品详情*/
    public function detail($id = 0) {
        $info = $this->goodsModel->where('id', $id)->find();
        if (!$info) {
            throw new ValidateException('未获取到详情');
        }

        $info['body'] = Utils::richTextAbsoluteUrl( $info['body'], request()->domain());

        return $info;
    }

    public function submit() {


        return true;
    }


    //创建订单（此方法用于创建由购物车提交上来的多商品订单）
    public function createOrder()
    {
        //购物车表编号
        $ids = Utils::explodeStr($this->request->param()['ids']);
        //积分
        $scoreTotal = 0;

        foreach ($ids as $key => $val) {
            //获取商品信息
            $info = $this->cartModel
                ->alias('cart')
                ->join('__LEESCORE_GOODS__ goods', 'goods.id = cart.goods_id')
                ->field('cart.*,goods.id,goods.scoreprice,goods.money,goods.thumb,goods.paytype,goods.status,goods.type,goods.name')
                ->where("cart.id", $val)->find();
            //购买数量
            $number = (int)$this->request->param("number_" . $val);
            $scoreTotal = $scoreTotal + ($info['scoreprice'] * $number);
        }

        //用户编号
        $data['uid'] = UID;
        //生成订单号  表前缀 + 时间戳10位 + 微秒3位 + 随机数4位
        $sn = Random::uuid();
        $data['order_id'] = $sn;
        //收货地址
        $data['address_id'] = '';
        //支付状态 0未付款 1已付款 2已退款
        $data['pay'] = 0;
        //订单状态： -2=驳回, -1=取消订单,0=未支付,1=已支付,2=已发货,3=已签收,4=退货中,5=已退款
        $data['status'] = 0;
        //支付时间
        //$data['paytime'] = time();
        //付款方式，score = 积分付款, weixin = 微信支付 , alipay = 支付宝 , paypal = paypal
        //$data['paytype'] = '';
        //删除订单（软删除）
        $data['isdel'] = 0;
        //订单创建时间
        $data['createtime'] = time();
        //需支付总积分
        $data['score_total'] = $scoreTotal;
        //需支付总款
        $data['money_total'] = 0;
        //自动清理订
        $data['auth_clear_level'] = 0;


        //需支付总款
        Db::startTrans();
        try {
            //创建订单
            $this->orderModel->insert($data);
            $lastid = $this->orderModel->getLastInsID();
            foreach ($ids as $k => $v) {
                $numbers = (int)$this->request->param("number_" . $v);
                if ($numbers <= 0) {
                    throw new ValidateException('购买数量不能小于1');
                }
                //从购物车中获取商品信息
                $info = $this->cartModel->with('goodsDetail')->where("id", $v)->find();
                $this->isCheck($info->goods_id, $numbers); //检车库存
                $order_goods['order_id'] = $lastid;
                $order_goods['goods_id'] = $info->goods_id;
                $order_goods['buy_num'] = $numbers;
                $order_goods['score'] = $info->goods_detail->scoreprice;
                $order_goods['money'] = $info->goods_detail->money;
                $order_goods['goods_name'] = $info->goods_detail->name;
                $order_goods['goods_thumb'] = $info->goods_detail->thumb;
                $order_goods['createtime'] = time();
                $this->orderGoodsModel->insert($order_goods);
                Db::commit();
            }
        } catch (\Exception $e) {
            Db::rollback();
            throw new ValidateException($e->getMessage());
        }


        return $lastid;
    }

    /**
     * @param $id 商品ID
     * @param $number 购买数量
     * return array;
     */

    public function isCheck($id, $number)
    {
        //积分验证
        $info = $this->goodsModel->where("id", $id)->find();
        $score_total = $info['scoreprice'] * $number;
        if ($this->auth->score < $score_total) {
            throw new ValidateException('积分不足');
        }

        //库存验证
        if ($info['stock'] < 1) {
            throw new ValidateException($info['name'] . '库存不足');
        }


        return $info;
    }


    //创建单词订单
    public function createOrderOne()
    {
        //商品ID
        $id = input("id/d", 0);
        //商品数量
        $number = input('number/d', 1);
        $goodsDetail = $this->isCheck($id, $number);
        //积分
        $scoreTotal = (int)($goodsDetail['scoreprice'] * $number);

        //用户编号
        $data['uid'] = UID;
        //生成订单号  表前缀 + 时间戳10位 + 微秒3位 + 随机数4位
        $sn = Random::uuid();
        $data['order_id'] = $sn;
        //收货地址
        $data['address_id'] = '';
        //支付状态 0未付款 1已付款 2已退款
        $data['pay'] = 0;
        //订单状态： -2=驳回, -1=取消订单,0=未支付,1=已支付,2=已发货,3=已签收,4=退货中,5=已退款
        $data['status'] = 0;
        //支付时间
        //$data['paytime'] = time();
        //付款方式，score = 积分付款, weixin = 微信支付 , alipay = 支付宝 , paypal = paypal
        //$data['paytype'] = '';
        //删除订单（软删除）
        $data['isdel'] = 0;
        //订单创建时间
        $data['createtime'] = time();
        //需支付总积分
        $data['score_total'] = $scoreTotal;
        //需支付总款
        Db::startTrans();
        try {
            //创建订单
            $this->orderModel->insert($data);
            $lastid = $this->orderModel->getLastInsID();
            $goods_data['order_id'] = $lastid;
            $goods_data['goods_id'] = $goodsDetail['id'];
            $goods_data['buy_num'] = $number;
            $goods_data['score'] = $goodsDetail['scoreprice'];
            $goods_data['money'] = $goodsDetail['money'];
            $goods_data['goods_name'] = $goodsDetail['name'];
            $goods_data['goods_thumb'] = $goodsDetail['thumb'];
            $goods_data['createtime'] = time();

            //写入订单商品表
            $this->orderGoodsModel->insert($goods_data);

            $dec['id'] = $goodsDetail['id'];
            //减少库存
            //$this->goodsModel->where($dec)->setDec('stock', $number);
            // 提交事务
            Db::commit();
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
        }

        return $lastid;
    }

    /**
     * 商品清单确认
     * @param $orderid 订单id
     */
    public function postOrders($orderid, $check = true)
    {
        $w['uid'] = UID;
        $w['isdel'] = 0;

        //获取默认收获地址

        $order = $this->orderModel
            ->with("orderGoods")
            ->where("id", $orderid)
            ->find();

        if ($order['address_id']) {
            $address = (new AddressLogic())->detail($order['address_id']);
        } else {
            $address = (new AddressLogic())->getDefault();
        }

        if (!$order) {
            throw new ValidateException('订单不存在');
        } else {
            if ($check == true) {
                if ($order['status'] != 0) {
                    throw new ValidateException('不能重复购买');
                }
            }
        }

        return [
            'address' => $address,
            'order'   => $order
        ];
    }


    //开始支付 $auth为权限
    public function pay($auth)
    {
        //订单ID
        $oid = input('post.oid');
        //用户收货地址
        $address = input("post.address");

        //检测收货地址
        $address = Leeaddress::get(['id'=> $address, 'uid'=>UID]);
        if (!$address) {
           throw new ValidateException('请正确填写收货地址');
        }
        $order = $this->orderModel->where("id", $oid)->find();

        if (!$order) {
            throw new ValidateException('订单不存在');
        }

        //需支付积分
        $scoreTotal = $order['score_total'];

        if ($auth->score < $order['score_total']) {
            throw new ValidateException('积分不足');
        }


        //收货地址
        $data['address_id'] = $address->id;
        //支付状态 0未付款 1已付款 2已退款
        //付款方式，score = 积分付款, weixin = 微信支付 , alipay = 支付宝 , paypal = paypal
        $data['paytype'] = 'score';
        //用户备注
        //需支付总积分
        $data['score_total'] = $scoreTotal;
        $data['auth_clear_level'] = 2;

        $map['id'] = $oid;
        if ($order['status'] != 0) {
            throw new ValidateException('不能重复购买');
        }

        $this->orderModel->where($map)->update($data);

        //仅有积分商品，直接操作库存，启动事务,确保数据一致性。
        Db::startTrans();
        try {
            //写入积分日志
            \app\common\model\User::score(-$scoreTotal, $auth->id, '消费积分兑换商品', $oid, 1);

            $orderData = [
                'pay'         => 1,  //已支付
                'status'      => 1,
                'paytime'     => time(),
                'trade_score' => $scoreTotal,
                'trade_money' => 0,
                'paytype'     => 'score'
            ];
            //扣除积分后，修改支付状态
            $this->orderModel->where('id', $oid)->update($orderData);
            //如果此商品在购物车中存在，就从购物车中移除。因为已经购买成功了。
            $order_goods = $this->orderGoodsModel->where('order_id', $order['id'])->select();
            if ($order_goods) {
                foreach ($order_goods as $key => $val) {
                    //购买成功 增加库存
                    // 减少商品库存
                    $this->goodsModel->where("id",  $val['goods_id'])->setDec('stock', $val['buy_num']);
                    //正价已兑换数量
                    $this->goodsModel->where("id",  $val['goods_id'])->setInc('usenum', $val['buy_num']);
                    //购买记录
                    $log = ['uid' => $auth->id, 'goods_id' => $val['goods_id'], 'order_id' => $order['id'], 'createtime' => time(), 'ip' => $this->request->ip()];
                    Db::name('leescore_exchangelog')->insert($log);

                    $cart = $this->cartModel->where('goods_id', $val['goods_id'])->find();
                    if ($cart) {
                        $cart->delete();
                    }
                }
            }
            Db::commit();
        } catch (\Exception $e) {
            //数据同步写入或修改时发生错误，回滚数据至修改前
            Db::rollback();
            throw new ValidateException($e->getMessage());
        }

    }


    /**
     * 从购物车中删除
     */
    //删除
    public function delete()
    {
        $ids = Utils::explodeStr($this->request->param()['ids']);
        try {
            $w['id'] = array('in', $ids);
            $w['uid'] = $this->auth->id;
            $this->cartModel->where($w)->delete();

            return true;
        } catch (\Exception $e) {
            throw new ValidateException($e->getMessage());
        }
    }

    //设置订单收获地址
    public function setAddress() {
        $orderid = input('orderid/d', 0);
        $address_id = input('address_id/d', 0);
        if (!$address_id) {
            throw new ValidateException('请传递地址id');
        }

        $this->orderModel->where(['id'=> $orderid])->setField('address_id', $address_id);

        return true;
    }
}
